package com.batunite.livedatabinding.views

import android.animation.Animator
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import com.batunite.livedatabinding.model.Map90Data

class BoxMapView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
    private val paint = Paint()
    private val blockSize = 100 // 方块的大小
    private val boxColor = Color.GRAY
    private val wallColor = Color.BLACK
    private val targetColor = Color.GREEN
    private val boxPlayerColor = Color.BLUE

    private val mapData = Map90Data.mapDataList[1]

     var playerX = 0
     var playerY = 0
    private var boxX = 0
    private var boxY = 0

    private var playerTargetX = 0
    private var playerTargetY = 0
    private var boxTargetX = 0
    private var boxTargetY = 0

    private var isAnimating = false

    init {
        // 设置动画插值器
        paint.isAntiAlias = true
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        // 绘制地图
        for (i in mapData.indices) {
            for (j in mapData[i].indices) {
                val left = j * blockSize
                val top = i * blockSize
                val right = left + blockSize
                val bottom = top + blockSize

                when (mapData[i][j]) {
                    0 -> {} // 空
                    1 -> {
                        paint.color = wallColor
                        canvas.drawRect(
                            left.toFloat(),
                            top.toFloat(),
                            right.toFloat(),
                            bottom.toFloat(),
                            paint
                        )
                    }

                    2 -> {
                        paint.color = targetColor
                        canvas.drawRect(
                            left.toFloat(),
                            top.toFloat(),
                            right.toFloat(),
                            bottom.toFloat(),
                            paint
                        )
                    }

                    3 -> {
                        paint.color = boxColor
                        canvas.drawRect(
                            left.toFloat(),
                            top.toFloat(),
                            right.toFloat(),
                            bottom.toFloat(),
                            paint
                        )
                    }

                    4 -> {
                        paint.color = boxPlayerColor
                        canvas.drawRect(
                            left.toFloat(),
                            top.toFloat(),
                            right.toFloat(),
                            bottom.toFloat(),
                            paint
                        )
                    }
                }
            }
        }

        // 绘制人物和箱子的移动动画
        if (isAnimating) {
            val playerLeft = playerX * blockSize
            val playerTop = playerY * blockSize
            val playerRight = playerLeft + blockSize
            val playerBottom = playerTop + blockSize
            paint.color = boxPlayerColor
            canvas.drawRect(
                playerLeft.toFloat(),
                playerTop.toFloat(),
                playerRight.toFloat(),
                playerBottom.toFloat(),
                paint
            )

            val boxLeft = boxX * blockSize
            val boxTop = boxY * blockSize
            val boxRight = boxLeft + blockSize
            val boxBottom = boxTop + blockSize
            paint.color = boxColor
            canvas.drawRect(
                boxLeft.toFloat(),
                boxTop.toFloat(),
                boxRight.toFloat(),
                boxBottom.toFloat(),
                paint
            )
        }
    }

    fun movePlayerAndBox(targetX: Int, targetY: Int) {
        if (isAnimating) {
            // 如果正在播放动画，则忽略新的移动请求
            return
        }

        if (!isValidMove(targetX, targetY)) {
            // 移动目标位置无效，不执行移动操作
            return
        }

        playerTargetX = targetX
        playerTargetY = targetY

        // 判断目标位置是否有箱子
        if (mapData[targetY][targetX] == 3) {
            // 计算箱子的目标位置
            val offsetX = targetX - playerX
            val offsetY = targetY - playerY
            boxTargetX = targetX + offsetX
            boxTargetY = targetY + offsetY
        } else {
            // 目标位置没有箱子
            boxTargetX = -1
            boxTargetY = -1
        }

        // 开始播放移动动画
        startAnimation()
    }

    private fun isValidMove(targetX: Int, targetY: Int): Boolean {
        // 判断目标位置是否超出边界或是墙
        if (targetX < 0 || targetX >= mapData[0].size || targetY < 0 || targetY >= mapData.size || mapData[targetY][targetX] == 1) {
            return false
        }

        // 判断目标位置是否有箱子
        if (mapData[targetY][targetX] == 3) {
            // 判断箱子的目标位置是否超出边界或是墙
            val offsetX = targetX - playerX
            val offsetY = targetY - playerY
            val boxTargetX = targetX + offsetX
            val boxTargetY = targetY + offsetY
            if (boxTargetX < 0 || boxTargetX >= mapData[0].size || boxTargetY < 0 || boxTargetY >= mapData.size || mapData[boxTargetY][boxTargetX] == 1) {
                return false
            }
        }

        return true
    }

    private fun startAnimation() {
        isAnimating = true

        // 创建两个属性动画，分别控制人物和箱子的位置变化
        val playerAnimatorX =
            ObjectAnimator.ofFloat(this, "playerX", playerX.toFloat(), playerTargetX.toFloat())
        val playerAnimatorY =
            ObjectAnimator.ofFloat(this, "playerY", playerY.toFloat(), playerTargetY.toFloat())
        playerAnimatorX.duration = 300
        playerAnimatorY.duration = 300
        playerAnimatorX.interpolator = AccelerateDecelerateInterpolator()
        playerAnimatorY.interpolator = AccelerateDecelerateInterpolator()

        var boxAnimatorX: ObjectAnimator? = null
        var boxAnimatorY: ObjectAnimator? = null
        if (boxTargetX != -1 && boxTargetY != -1) {
            boxAnimatorX =
                ObjectAnimator.ofFloat(this, "boxX", boxX.toFloat(), boxTargetX.toFloat())
            boxAnimatorY =
                ObjectAnimator.ofFloat(this, "boxY", boxY.toFloat(), boxTargetY.toFloat())
            boxAnimatorX.duration = 300
            boxAnimatorY.duration = 300
            boxAnimatorX.interpolator = AccelerateDecelerateInterpolator()
            boxAnimatorY.interpolator = AccelerateDecelerateInterpolator()
        }

        // 监听动画结束事件
        playerAnimatorX.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator) {}
            override fun onAnimationRepeat(animation: Animator) {}
            override fun onAnimationCancel(animation: Animator) {}

            override fun onAnimationEnd(animation: Animator) {
                // 动画结束后更新位置
                playerX = playerTargetX
                playerY = playerTargetY
                if (boxAnimatorX != null && boxAnimatorY != null) {
                    boxX = boxTargetX
                    boxY = boxTargetY
                }
                isAnimating = false
                invalidate()
            }
        })

        // 启动动画
        val animatorSet = AnimatorSet()
        animatorSet.play(playerAnimatorX).with(playerAnimatorY)
        if (boxAnimatorX != null && boxAnimatorY != null) {
            animatorSet.play(boxAnimatorX).with(boxAnimatorY)
        }
        animatorSet.start()
    }

    fun setPlayerX(x: Float) {
        playerX = x.toInt()
        invalidate()
    }

    fun setPlayerY(y: Float) {
        playerY = y.toInt()
        invalidate()
    }

    fun setBoxX(x: Float) {
        boxX = x.toInt()
        invalidate()
    }

    fun setBoxY(y: Float) {
        boxY = y.toInt()
        invalidate()
    }
}
